package org.rcgwt.client.ui.validator.impl;

import java.util.Map;

import org.rcgwt.client.ui.validator.IChecker;
import org.rcgwt.client.ui.validator.IClientValidatorContext;
import org.rcgwt.client.ui.validator.messages.Severity;

/**
 * A Credit Card Number checker that implements the Luhn algorithm
 * 
 * @author Elian ORIOU
 * 
 */

public class CreditCardNumberChecker implements IChecker {

	private int length;

	public CreditCardNumberChecker(Map<String, String> parameters) {
		if (parameters.containsKey("creditCard.number_length")) {
			length = Integer.parseInt(parameters
					.get("creditCard.number_length"));
		}
	}

	@Override
	public boolean check(IClientValidatorContext context, String num) {

		if (num.length() > length) {
			context.addMessage(context.getMessagesProvider()
					.StructureErrorShort(), context.getMessagesProvider()
					.StructureError(), Severity.ERROR);
			return false;
		}
		final int[][] sumTable = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
				{ 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 } };
		int sum = 0;
		int flip = 0;

		for (int i = num.length() - 1; i >= 0; i--, flip++) {
			sum += sumTable[flip & 0x1][Character.digit(num.charAt(i), 10)];
		}

		if (sum % 10 == 0) {
			return true;
		} else {
			context.addMessage(context.getMessagesProvider()
					.InvalidNumberErrorShort(), context.getMessagesProvider()
					.InvalidNumberError(), Severity.ERROR);
			return false;
		}
	}
}
